package models

import (
	"context"
	"time"
)

// 红包金额类型常量
const (
	RedPacketAmountTypeFixed  = 1 // 固定金额
	RedPacketAmountTypeRandom = 2 // 随机金额
	RedPacketAmountTypeRate   = 3 // 比例金额
)

// 红包规则状态常量
const (
	RedPacketRuleStatusEnabled  = 1 // 启用
	RedPacketRuleStatusDisabled = 2 // 禁用
)

// RedPacketRule 红包规则表
type RedPacketRule struct {
	Id           int64     `json:"id" xorm:"pk autoincr"`
	Name         string    `json:"name" xorm:"varchar(50) not null comment('规则名称')"`
	Source       string    `json:"source" xorm:"varchar(50) not null comment('红包来源') index"`
	AmountType   int       `json:"amount_type" xorm:"tinyint(4) not null comment('金额类型:1固定 2随机 3比例')"`
	MinAmount    float64   `json:"min_amount" xorm:"decimal(10,2) not null comment('最小金额')"`
	MaxAmount    float64   `json:"max_amount" xorm:"decimal(10,2) not null comment('最大金额')"`
	Rate         float64   `json:"rate" xorm:"decimal(10,2) null comment('比例(百分比)')"`
	ValidDays    int       `json:"valid_days" xorm:"not null default 0 comment('有效期(天)')"`
	LimitCount   int       `json:"limit_count" xorm:"not null default 0 comment('每人限领次数')"`
	LimitCycle   string    `json:"limit_cycle" xorm:"varchar(20) null comment('限领周期')"`
	UseThreshold float64   `json:"use_threshold" xorm:"decimal(10,2) not null default 0 comment('使用门槛')"`
	Status       int       `json:"status" xorm:"tinyint(4) not null default 1 comment('状态') index"`
	StartTime    time.Time `json:"start_time" xorm:"datetime null comment('开始时间')"`
	EndTime      time.Time `json:"end_time" xorm:"datetime null comment('结束时间')"`
	Remark       string    `json:"remark" xorm:"varchar(255) null comment('规则说明')"`
	UpdateTime   time.Time `json:"update_time" xorm:"not null updated comment('更新时间')"`
	CreateTime   time.Time `json:"create_time" xorm:"not null created comment('创建时间')"`
}

// TableName 表名
func (RedPacketRule) TableName() string {
	return "red_packet_rule"
}

// GetRedPacketRule 获取红包规则
func GetRedPacketRule(ctx context.Context, source string) (*RedPacketRule, error) {
	var rule RedPacketRule
	exists, err := Get(ctx, &rule, "source = ? AND status = ? AND (start_time IS NULL OR start_time <= NOW()) AND (end_time IS NULL OR end_time >= NOW())",
		source, RedPacketRuleStatusEnabled)
	if err != nil {
		return nil, err
	}
	if !exists {
		return nil, nil
	}
	return &rule, nil
}

// CheckUserLimit 检查用户领取限制
func (r *RedPacketRule) CheckUserLimit(ctx context.Context, userId int64) (bool, error) {
	if r.LimitCount == 0 {
		return true, nil
	}

	// 构建时间范围
	var startTime time.Time
	now := time.Now()
	switch r.LimitCycle {
	case "day":
		startTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location())
	case "week":
		weekday := now.Weekday()
		if weekday == 0 {
			weekday = 7
		}
		startTime = time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()).
			AddDate(0, 0, -int(weekday-1))
	case "month":
		startTime = time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location())
	case "year":
		startTime = time.Date(now.Year(), 1, 1, 0, 0, 0, 0, now.Location())
	default:
		return true, nil
	}

	// 查询领取次数
	count, err := Count(ctx, &RedPacketRecord{},
		"user_id = ? AND source = ? AND type = ? AND create_time >= ?",
		userId, r.Source, RedPacketTypeIncome, startTime)
	if err != nil {
		return false, err
	}

	return count < int64(r.LimitCount), nil
}

// CalculateAmount 计算红包金额
func (r *RedPacketRule) CalculateAmount(baseAmount float64) float64 {
	switch r.AmountType {
	case RedPacketAmountTypeFixed:
		return r.MinAmount
	case RedPacketAmountTypeRandom:
		// 随机金额,这里简单返回最小金额,实际应该实现随机算法
		return r.MinAmount
	case RedPacketAmountTypeRate:
		if r.Rate <= 0 {
			return 0
		}
		amount := baseAmount * r.Rate / 100
		if amount < r.MinAmount {
			amount = r.MinAmount
		}
		if amount > r.MaxAmount {
			amount = r.MaxAmount
		}
		return amount
	default:
		return 0
	}
}
